#include "StdAfx.h"
#include "SMS.h"

CSMS::CSMS()
{
	sys.SetVideo(256,224,32);
	sys.SetSound(44100);
}

CSMS::~CSMS()
{
}

int CSMS::Load(char *fn)
{
/*	FILE *fp;

	if((fp = fopen(fn,"rb")) == 0) {
		message("cannot open '%s'\n",fn);
		return(1);
	}
	fseek(fp,SEEK_END,0);
	romsize = ftell(fp);
	rom = new u8[romsize];
	fseek(fp,SEEK_SET,0);
	if(fread(rom,1,romsize,fp) != romsize) {
		message("error reading '%s'\n",fn);
		return(2);
	}
	fclose(fp);*/
	HANDLE hFile = CreateFile(fn,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
	DWORD sz;
	OVERLAPPED ov = {0};

	//=== On failure CreateFile returns -1
	if (hFile == (HANDLE)-1)
	{
		MessageBox(NULL,"Could not open this file", "File I/O Error", MB_ICONSTOP);
		return FALSE;
	}
	sz = GetFileSize(hFile,NULL);
	romsize = (int)sz;
	rom = new u8[romsize];
	ReadFile(hFile,rom,(DWORD)romsize,&sz,&ov);
	CloseHandle(hFile);
	return(0);
}

void CSMS::Unload()
{
	if(rom)
		delete[] rom;
	rom = 0;
}

void CSMS::Reset(int hard)
{
	int i;

	for(i=0;i<0xC;i++) {
		z80.SetReadPage(i,rom + (i&7) * 0x1000);
	}
	z80.SetReadPage(0xC,wram);
	z80.SetReadPage(0xD,wram+0x1000);
	z80.SetReadPage(0xE,wram);
	z80.SetReadPage(0xF,wram+0x1000);
	z80.SetWritePage(0xC,wram);
	z80.SetWritePage(0xD,wram+0x1000);
	z80.SetWritePage(0xE,wram);
//	z80.SetWritePage(0xF,wram+0x1000);
	z80.SetWrite(0xF,pagingwrite);
	z80.SetUser((void*)this);
	z80.SetIORead(ioread);
	z80.SetIOWrite(iowrite);
	z80.Reset();
	vdp.Reset();
}

void CSMS::Frame()
{
	z80.Execute(100);
}
void CSMS::Step()
{
	z80.Execute(1);
}

u8 CSMS::ioread(void *user,u32 addr)
{
	CSMS *sms = (CSMS*)user;
	u8 mask = addr & 0xC1;

	switch(mask & 0xC1) {
		case 0x00:	//JOYPAD3
			message("input 3 port read (addr = $%04X)\n",addr);
			return(0);
		case 0x01:	//nothing here to read
			break;
		case 0x40:	//CURLINE
		case 0x41:	//??
		case 0x80:	//VDPDATA
		case 0x81:	//VDPSTAT 
			return(sms->vdp.Read((u8)addr));
		case 0xC0:	//JOYPAD1
			message("input 1 port read (addr = $%04X)\n",addr);
			return(0);
		case 0xC1:	//JOYPAD2
			message("input 2 port read (addr = $%04X)\n",addr);
			return(0);
	}
	return(0);
}

void CSMS::iowrite(void *user,u32 addr,u8 data)
{
	CSMS *sms = (CSMS*)user;
	u8 mask = addr & 0xC1;

	if((addr & 0xFF) == 0xFD) {
		message("%c",data);
	//	return;
	}
//	else message("iowrite: $%04X = $%02X",addr,data);
	switch(mask & 0xC1) {
		case 0x00:	//nothing here to write
		case 0xC0:
		case 0xC1:
			break;
		case 0x01:	//GUNPORT
			break;
		case 0x40:	//PSGPORT
		case 0x41:	//?? PSGPORT
		case 0x80:	//VDPDATA
		case 0x81:	//VDPCTRL 
			sms->vdp.Write((u8)addr,data);
			break;
	}
}

void CSMS::pagingwrite(void *user,u32 addr,u8 data)
{
	CSMS *sms = (CSMS*)user;

	sms->wram[0x1000 + (addr & 0xFFF)] = data;
	if(addr >= 0xFFFC) {
//		message("paging write: %04X = $%02X\n",addr,data);
	}
}
